use std::process::Command;
use std::string::ParseError;
use structopt::StructOpt;
use url::Url;

const HD: &str = "606"; // see --list-formats
const LOWREZ: &str = "603";

/// Watch (or try watching) a video over tor, using a combination of mpv and Invidious
/// infrastructure.
#[derive(Debug, StructOpt)]
struct Opt {
    /// Url to watch. Can be Youtube or Invidious
    #[structopt(parse(try_from_str = url_from_str))]
    url: Url,
    /// Pick a higher resolution (default is 480p to not strain the network)
    #[structopt(long = "720")]
    hd: bool,
    /// Audio-only mode (minimal bandwidth)
    #[structopt(long = "audio")]
    audio: bool,
}

fn url_from_str(url: &str) -> Result<Url, ParseError> {
    let parsed: Url = Url::parse(url).unwrap();
    return Ok(parsed);
}

fn mpv_resolution_option(options: &Opt) -> String {
    let rez = match options.hd {
        true => HD.to_string(),
        false => LOWREZ.to_string(),
    };
    let res = String::from("--ytdl-format=") + &rez;
    return res;
}

fn main() {
    let options = Opt::from_args();
    let mpv_rez_option = mpv_resolution_option(&options);

    let mut url = options.url;
    url.set_host(Some("vid.puffyan.us")).unwrap();
    let url: String = url.into();

    let mut torsocks_args = vec!["-i", "mpv", &url];
    if options.audio {
        torsocks_args.push("--vid=no");
    } else {
        torsocks_args.push(&mpv_rez_option);
    }

    let mut child = Command::new("torsocks")
        .args(torsocks_args)
        .spawn()
        .expect("cannot download");

    child.wait().expect("Exited abnormally!");
}
